// DriveNotes. Copyright (c) 2011, Andrei Senchuk. All rights reserved.
package net.taviscaron.drivenotes.web.action;

import java.io.IOException;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.taviscaron.drivenotes.shared.exceptions.InvalidEntityException;
import net.taviscaron.drivenotes.shared.model.entity.Note;
import net.taviscaron.drivenotes.shared.model.entity.User;
import net.taviscaron.drivenotes.shared.service.NoteService;
import net.taviscaron.drivenotes.web.converter.FormConverter;
import net.taviscaron.drivenotes.web.converter.InvalidFormException;
import net.taviscaron.drivenotes.web.core.Constants;
import net.taviscaron.drivenotes.web.forward.ActionRedirect;
import net.taviscaron.drivenotes.web.forward.RequestForwarder;
import net.taviscaron.drivenotes.web.forward.ViewForward;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;

/**
 * Note edit action
 * @author Andrei Senchuk
 */
public class NoteEditAction implements Action {
    public enum Error {
        BAD_PARAM
    }

    private static final Log logger = LogFactory.getLog(NoteEditAction.class);
    private NoteService noteService;
    private FormConverter<Note> noteConverter;

    @Required
    public void setNoteConverter(FormConverter<Note> noteConverter) {
        this.noteConverter = noteConverter;
    }

    @Required
    public void setNoteService(NoteService noteService) {
        this.noteService = noteService;
    }

    public RequestForwarder doAction(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String subaction = request.getParameter(Constants.SUBACTION_PARAM_NAME);

        if (subaction == null) {
            return newAction(request, response);
        } else if ("save".equals(subaction)) {
            return saveAction(request, response);
        } else if ("del".equals(subaction)) {
            return deleteAction(request, response);
        } else {
            logger.warn("bad subaction: " + subaction);
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "bad subaction");
            return null;
        }
    }

    public RequestForwarder deleteAction (HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Long noteId;
        try {
            noteId = Long.valueOf(request.getParameter("noteId"));
        } catch (NumberFormatException e) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return null;
        }

        Note note = noteService.findNote(noteId, user);
        if(note != null) {
            noteService.removeNoteById(noteId);
            return new ActionRedirect("notes");
        } else {
            logger.warn("user '" + user.getUsername() + "' trying to remove not existing or not owned note with id: " + noteId);
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return null;
        }
    }

    public RequestForwarder saveAction (HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Note note = null;
        try {
            note = noteConverter.convert(request.getParameterMap());
            note.setAuthor(user);

            Date time = GregorianCalendar.getInstance().getTime();

            if (note.getId() != null) {
                Note original = noteService.findNote(note.getId(), user);
                if(original == null) {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    return null;
                } else {
                    note.setCreateTime(original.getCreateTime());
                }
            } else {
                note.setCreateTime(time);
            }

            note.setEditTime(time);

            noteService.saveNote(note);

            return new ActionRedirect("notes");
        } catch (InvalidFormException e) {
            request.setAttribute("error", Error.BAD_PARAM);
            return new ViewForward("noteEdit");
        } catch(InvalidEntityException e) {
            request.setAttribute("error", e.getReason());
            return new ViewForward("noteEdit");
        }
    }

    public RequestForwarder newAction (HttpServletRequest request, HttpServletResponse response) throws IOException {
        User user = (User)request.getAttribute(Constants.AUTHORIZED_USER_ATTR_NAME);
        Long noteId;

        if(request.getParameter("noteId") != null) {
            try {
                noteId = Long.valueOf(request.getParameter("noteId"));
            } catch (NumberFormatException e) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return null;
            }
            Note note = noteService.findNote(noteId, user);
            request.setAttribute("note", note);

        }
        return new ViewForward("noteEdit");
    }
}
